<template>
  <view class="content">
    <!-- <image class="logo" src="/static/logo.png"></image> -->
    <button @click="getAddr">0. 定位</button>
    <view class="text-area">
      <button @click="initBlue">1. 初始化蓝牙</button>
      <button @click="discovery">2. 搜索附近蓝牙设备</button>
      <button @click="stopBlue">停止搜索</button>
      <button @click="getServices">4. 获取蓝牙服务</button>

    </view>
    <view>
      <button @click="getCharacteristics">5. 获取指定服务的特征值</button>
      <button @click="searchIb">6 搜索附近的iBeacon设备</button>
      <button @click="stopIb">停止搜索iBeacon 设备</button>
      <button @click="jisuan(1)">1s处的rssi</button>
      {{ oneData }}
      滤波后的值{{ onerawDistance }}
      <button @click="jisuan(6)">6s处的rssi</button>
      {{ sixData }}
      滤波后的值{{ sixrawDistance }}
      <button @click="jisuanssad">计算</button>


    </view>
    <scroll-view scroll-y class="box">
      <view class="item" v-for="item in blueDeviceList" @click="connect(item)">
        <view>
          <text>id: {{ item.deviceId }}</text>
        </view>
        <view>
          <text>name: {{ item.name }}</text>
        </view>
        <view>
          <text>advertisData: {{ ab2hex(item.advertisData) }}</text>
        </view>
      </view>
    </scroll-view>

    <!--     隐私协议弹层 -->
    <!-- <PrivacyPop ref="PrivacyPopck" /> -->
  </view>
</template>

<script>
// import PrivacyPop from '@/components/PrivacyPop.vue';
import KalmanFilter from 'kalmanjs';

export default {
  components: {
    // PrivacyPop
  },
  data() {
    return {
      title: '点我搜索',
      stop: '停止搜索',
      blueDeviceList: [],
      deviceId: "",
      uuid: [],
      characteristicsList: [],
      guangBoUUid: ['01122334-4126-6778-899a-abbc14deeff0'],
      rssiHistory: {},
      oneData: [],
      sixData: [],
      onerawDistance: 0,
      sixrawDistance: 0,
    }
  },
  onLoad() {
    console.log(333333);

    // this.$refs.PrivacyPopck.checkPrivacySetting();




  },
  methods: {
    getAddr() {
      uni.getLocation({
        type: 'wgs84',
        success: function (res) {
          console.log('当前位置的经度：' + res.longitude);
          console.log('当前位置的纬度：' + res.latitude);
        },
        fail: function (err) {
          console.log('获取位置失败', err);
        }
      });
      // wx.authorize({
      //   scope: 'scope.userLocation',
      //   success() {
      //     console.log('用户已授权');
      //   },
      //   fail() {
      //     console.log('用户未授权');
      //   }
      // });
      // wx.authorize({
      //   scope: 'scope.bluetooth',
      //   success() {
      //     console.log('l用户已授权');
      //   },
      //   fail() {
      //     console.log('l用户未授权');
      //   }
      // });
      let taht = this;
      uni.getLocation({
        type: 'gcj02', // 使用 WGS84 坐标系，常用于 GPS 定位
        success(res) {
          console.log('经度:', res.longitude); // 获取经度
          console.log('纬度:', res.latitude); // 获取纬度
          console.log('速度:', res.speed); // 获取速度
          console.log('精度:', res.accuracy); // 定位精度

        },
        fail(err) {
          console.error('定位失败', err);
        }
      });

    },
    //停止搜索附近的 iBeacon 设备
    stopIb() {
      uni.stopBeaconDiscovery({
        success: res => {
          console.log("ib 停止成功", res)
        },
        fail: res => {
          console.log("ib 停止失败", res)
        }

      })

    },
    //停止
    stopBlue() {
      uni.stopBluetoothDevicesDiscovery({
        success: res => {
          console.log(res, "停止成功")
        },
        fail: res => {
          console.log(res, "停止失败")
        }
      })

    },
    //【1】初始化蓝牙
    initBlue() {
      let taht = this;
      uni.openBluetoothAdapter({
        success(res) {
          console.log('初始化蓝牙成功');
          console.log(res);

        },
        fail(err) {
          console.log('初始化蓝牙失败');
          console.error(err);
        }
      });
    },
    //2. 搜索蓝牙
    discovery() {
      const that = this;
      uni.startBluetoothDevicesDiscovery({
        success(res) {
          console.log('开始搜索', res);

          // 开启监听回调
          uni.onBluetoothDeviceFound(function (devices) {
            console.log('扫到的蓝牙', devices.devices[0])
            console.dir(devices)
            console.log(that.ab2hex(devices.devices[0].advertisData), '我是神那么雄性呢')
            if (devices) {
              if (devices.devices[0].name) {
                that.blueDeviceList.push(devices.devices[0]);
              }

            }
          });
        },
        fail(err) {
          console.log('搜索失败');
          console.error(err);
        }
      });
    },

    ab2hex(buffer) {
      const hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function (bit) {
          return ('00' + bit.toString(16)).slice(-2)
        }
      )
      return hexArr.join('')
    },
    // 3..连接蓝牙
    connect(data) {
      console.log("连接蓝牙", data);
      this.deviceId = data.deviceId;
      uni.createBLEConnection({
        deviceId: data.deviceId,
        success(res) {
          console.log('连接成功');
          console.log(res);
        },
        fail(err) {
          console.log('连接失败');
          console.error(err);
        }
      });
    },
    //4. 获取服务
    getServices() {
      const that = this;
      uni.getBLEDeviceServices({
        deviceId: this.deviceId,
        success(res) {
          console.log(res);
          if (res.services.length > 0) {
            res.services.forEach(item => {
              that.uuid.push(item.uuid);
            })
            console.log(that.uuid);
          }
        },
        fail(err) {
          console.error(err);
        }
      });
    },
    //5. 获取特征值
    getCharacteristics() {
      const that = this;
      uni.getBLEDeviceCharacteristics({
        deviceId: this.deviceId,
        serviceId: this.uuid[0],
        success(res) {
          console.log("5. 获取特征值 成功", res);
          if (res.characteristics.length > 0) {
            res.characteristics.forEach(item => {
              that.characteristicsList.push(item.uuid);
            })
            console.log(that.characteristicsList);
          }
        },
        fail(err) {
          console.error("5. 获取特征值 异常", err);
        }
      });

    },

    //6. 开始搜索附近的 iBeacon 设备
    searchIb() {
      console.log("guangBoUUid", this.guangBoUUid);

      // const kf = new KalmanFilter();
      // let temperatureReadings = [19.5, 20.1, 20.0, 19.8, 20.2]; // 示例读数数组

      // temperatureReadings.forEach(temp => {
      //   console.log(`Filtered Temperature Reading: ${kf.filter(temp)}`);
      // });


      // setInterval(() => {
      //   // 获取扫描到的所有 iBeacon 设备
      //   wx.getBeacons({
      //     success: function (res) {
      //       console.log('最终===>获取所有已搜索到的 iBeacon 设备');
      //       console.log(res);
      //     },
      //     fail: function (err) {
      //       console.log('最终===>获取所有已搜索到的 iBeacon 失败');
      //       console.log(err);
      //     }
      //   });
      // }, 5000); // 5000 毫秒 = 5 


      // 初始化卡尔曼滤波器
      // class KalmanFilter {
      //   constructor(initialEstimate = 0, initialError = 1, processNoise = 0.0001, measurementNoise = 0.1) {
      //     // 状态估计 (初始值)
      //     this.estimate = initialEstimate;
      //     // 估计误差协方差 (初始不确定性)
      //     this.estimationError = initialError;
      //     // 过程噪声 (系统动态噪声)
      //     this.processNoise = processNoise;
      //     // 测量噪声 (传感器噪声)
      //     this.measurementNoise = measurementNoise;
      //   }

      //   update(measurement) {
      //     // 预测步骤
      //     const predictionError = this.estimationError + this.processNoise;

      //     // 更新步骤
      //     const kalmanGain = predictionError / (predictionError + this.measurementNoise);
      //     this.estimate = this.estimate + kalmanGain * (measurement - this.estimate);
      //     this.estimationError = (1 - kalmanGain) * predictionError;

      //     return this.estimate;
      //   }
      // }


      // 存储不同Beacon的滤波器实例
      const beaconFilters = {};


      // RSSI转距离函数
      function calculateDistance(rssi, measuredPower = -61, n = 2) {
        if (rssi >= 0) return -1; // 无效值

        // 对数路径损耗模型
        const ratio = (measuredPower - rssi) / (10 * n);
        return Math.pow(10, ratio);
      }


      // 确保 uuids 是一个数组
      const that = this
      const uuids = Array.isArray(this.guangBoUUid) ? this.guangBoUUid : [this.guangBoUUid];
      // 启动 iBeacon 扫描
      wx.startBeaconDiscovery({
        uuids: ['FDA50693-A4E2-4FB1-AFCF-C6EB07647825'],
        success: res => {
          console.log("附近的 iBeacon 设备", res);
          // const kf = new KalmanFilter();

          // const asda = {}

          // 注册信标更新监听事件
          wx.onBeaconUpdate(function (res) {

            const beacons = res.beacons;

            // beacons.forEach(beacon => {
            //   const key = `${beacon.minor}`;

            //   // 初始化滤波器
            //   if (!beaconFilters[key]) {
            //     beaconFilters[key] = new KalmanFilter()
            //   }

            //   // beaconFilters[key].push(beacon.rssi)

            //   // RSSI转距离
            //   // const rawDistance = calculateDistance(beacon.rssi);



            //   // 卡尔曼滤波
            //   const filteredDistance = beaconFilters[key].filter(beacon.rssi)

            //   console.log("原始", beacon.rssi, '卡尔曼滤波后', filteredDistance)

            //   const rawDistance = calculateDistance(filteredDistance);

            //   // 使用滤波后的距离
            //   console.log(`Beacon ${key}:`, rawDistance, '米');
            // });

            const padp = beacons.map(beacon => {

              const key = `${beacon.minor}`;

              // 初始化滤波器
              if (!beaconFilters[key]) {
                beaconFilters[key] = {
                  Kalman: null,
                  data: [],
                  CHANGD: 0
                }
                beaconFilters[key].Kalman = new KalmanFilter()
                beaconFilters[key].data = []
              }


              if (beacon.rssi !== 0) {
                beaconFilters[key].data.push(beacon.rssi)
                // 卡尔曼滤波
                const filteredDistance = beaconFilters[key].Kalman.filter(beacon.rssi)
                // console.log("原始", beacon.rssi, '卡尔曼滤波后', filteredDistance)
                const rawDistance = calculateDistance(filteredDistance, -61, 1.1744);
                beaconFilters[key].rawDistance = filteredDistance
                beaconFilters[key].CHANGD = rawDistance
                // 使用滤波后的距离
                console.log(key, filteredDistance, '卡慢炖之后的值');
                console.log(beaconFilters[key], '我是数据呢');
              }

              return {
                ...beacon,
                jili: beaconFilters[key].rawDistance,
                CHANGD: beaconFilters[key].CHANGD,
              }

              // beaconFilters[key].data.push(beacon.rssi)

              // // RSSI转距离
              // // const rawDistance = calculateDistance(beacon.rssi);



              // // 卡尔曼滤波
              // const filteredDistance = beaconFilters[key].Kalman.filter(beacon.rssi)

              // // console.log("原始", beacon.rssi, '卡尔曼滤波后', filteredDistance)

              // const rawDistance = calculateDistance(filteredDistance, -61, 1.407052115246173);

              // // 使用滤波后的距离
              // console.log(key, beaconFilters[key].data, '我是存储的值', filteredDistance, '卡慢炖之后的值');

              // return {
              //   ...beacon,
              //   jili: rawDistance
              // }
            })

            console.log(padp, '我是爱哭的')


          });
          // setInterval(() => {
          // 	// 获取扫描到的所有 iBeacon 设备
          // 	wx.getBeacons({
          // 		success: function(res) {
          // 			console.log('最终===>获取所有已搜索到的 iBeacon 设备');
          // 			console.log(res);
          // 		},
          // 		fail: function(err) {
          // 			console.log('最终===>获取所有已搜索到的 iBeacon 失败');
          // 			console.log(err);
          // 		}
          // 	});
          // }, 5000); // 5000 毫秒 = 5 



        },
        fail: res => {
          console.log("附近的 iBeacon 设备失败", res);
        }
      });
      // 超时停止扫描
      setTimeout(function () {
        wx.stopBeaconDiscovery({
          success: function () {
            console.log("停止设备扫描！");
            //console.log(devices);
          }
        });
      }, 200 * 1000);
    },

    jisuan(params) {



      // 存储不同Beacon的滤波器实例
      const beaconFilters = {};


      // RSSI转距离函数
      function calculateDistance(rssi, measuredPower = -61, n = 2) {
        if (rssi >= 0) return -1; // 无效值

        // 对数路径损耗模型
        const ratio = (measuredPower - rssi) / (10 * n);
        return Math.pow(10, ratio);
      }


      // 确保 uuids 是一个数组
      const that = this
      const uuids = Array.isArray(this.guangBoUUid) ? this.guangBoUUid : [this.guangBoUUid];
      // 启动 iBeacon 扫描
      wx.startBeaconDiscovery({
        uuids: ['FDA50693-A4E2-4FB1-AFCF-C6EB07647825'],
        success: res => {
          console.log("附近的 iBeacon 设备", res);
          // const kf = new KalmanFilter();
          // const asda = {}
          // 注册信标更新监听事件
          wx.onBeaconUpdate(function (res) {
            const beacons = res.beacons;
            const padp = beacons.map(beacon => {
              const key = `${beacon.minor}`;
              // 初始化滤波器
              if (!beaconFilters[key]) {
                beaconFilters[key] = {
                  Kalman: null,
                  data: [],
                  rawDistance: 0
                }
                beaconFilters[key].Kalman = new KalmanFilter()
                beaconFilters[key].data = []
              }

              if (beacon.rssi !== 0) {
                beaconFilters[key].data.push(beacon.rssi)
                // 卡尔曼滤波
                const filteredDistance = beaconFilters[key].Kalman.filter(beacon.rssi)
                // console.log("原始", beacon.rssi, '卡尔曼滤波后', filteredDistance)
                // const rawDistance = calculateDistance(filteredDistance, -61, 2.8938205796504657);
                beaconFilters[key].rawDistance = filteredDistance
                // 使用滤波后的距离
                console.log(filteredDistance, '卡慢炖之后的值');
              }

              return {
                ...beacon,
                jili: beaconFilters[key].rawDistance
              }
            })
            console.log(padp, '我是爱哭的')
          });
        },
        fail: res => {
          console.log("附近的 iBeacon 设备失败", res);
        }
      });
      // 超时停止扫描
      setTimeout(function () {
        wx.stopBeaconDiscovery({
          success: function () {
            console.log(beaconFilters, '扫描结束')
            if (params == 1) {
              that.oneData = beaconFilters[2319].data
              that.onerawDistance = beaconFilters[2319].rawDistance
              console.log(beaconFilters[2319], '我是数据呢')
            } else {
              that.sixData = beaconFilters[2319].data
              that.sixrawDistance = beaconFilters[2319].rawDistance
            }
            console.log("停止设备扫描！");
            //console.log(devices);
          }
        });
      }, 300 * 1000);
    },
    calculateEnvFactor(avg1m, avg6m) {
      // // 数据校验
      // if (!Array.isArray(rssi1m) || !Array.isArray(rssi6m) ||
      //   rssi1m.length !== 100 || rssi6m.length !== 100) {
      //   throw new Error('需要提供100条1m和6m的RSSI数据');
      // }

      // // 计算平均值（过滤异常值）
      // const avg1m = rssi1m.reduce((sum, val) => sum + val, 0) / 100;
      // const avg6m = rssi6m.reduce((sum, val) => sum + val, 0) / 100;

      // 计算n值公式：n = (A - RSSI_d)/(10 * log10(d)) 
      // 其中A=avg1m, d=6, RSSI_d=avg6m
      const numerator = avg1m - avg6m;
      const denominator = 10 * Math.log10(6);

      return numerator / denominator;
    },
    jisuanssad() {
      const n = this.calculateEnvFactor(this.onerawDistance, this.sixrawDistance)
      console.log(this.onerawDistance, this.sixrawDistance, n, '我是环境因子')
    }


    // /**
    //  * 根据RSSI计算与iBeacon的物理距离
    //  * @param {number} rssi - 当前信号强度
    //  * @param {number} measuredPower - 1米处的参考RSSI（默认-59）
    //  * @param {number} envFactor - 环境衰减因子（默认2）
    //  * @return {number} 距离（米）
    //  */
    // calculateDistance(rssi, measuredPower = -59, envFactor = 2) {
    //   if (rssi >= 0) return -1; // 无效信号
    //   const ratio = (measuredPower - rssi) / (10 * envFactor);
    //   return Math.pow(10, ratio);
    // },
    // // EWMA滤波实现
    // smoothRssi(current, prev, alpha = 0.3) {
    //   return prev ? alpha * current + (1 - alpha) * prev : current;
    // }

  }
}



</script>

<style>
.content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.logo {
  height: 200rpx;
  width: 200rpx;
  margin-top: 200rpx;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 50rpx;
}

.text-area {
  display: flex;
  justify-content: center;
}

.title {
  font-size: 36rpx;
  color: #8f8f94;
}

.box {
  width: 100%;
  height: 400rpx;
  box-sizing: border-box;
  margin-bottom: 20rpx;
  border: 2px solid dodgerblue;
}

.item {
  box-sizing: border-box;
  padding: 10rpx;
  border-bottom: 1px solid #ccc;
}

button {
  margin-bottom: 20rpx;
}
</style>
